<script setup lang="ts">
import { ref, h } from "vue";
import { useColumns } from "./columns";
import { IconifyIconOnline } from "@/components/ReIcon";
import { PlusDialogForm } from "plus-pro-components";
import type {
  PlusColumn,
  FieldValues,
  PlusFormInstance
} from "plus-pro-components";
import { message } from "@/utils/message";
import { ElInput, ElUpload } from "element-plus";
import { UPLOAD_IMAGE_URL } from "@/api/images";
import { ImageItem } from "types/image";
import { adminChangePassword, deleteUser, registerUser } from "@/api/user";

const SERVER_URL = import.meta.env.VITE_SERVER_URL;

const tableRef = ref();

const {
  loading,
  columns,
  dataList,
  pagination,
  loadingConfig,
  adaptiveConfig,
  searchText,
  onSizeChange,
  onCurrentChange,
  refresh,
  search
} = useColumns({
  onChangePassword: (row, index) => {
    changePasswordData.value = {
      id: row.id,
      username: row.username
    };
    changePasswordFormVisible.value = true;
  },
  onDelete: async (row, index) => {
    try {
      await deleteUser(row.id);
      message("删除成功", { type: "success" });
      refresh();
    } catch (e) {
      if (e.response.data && e.response.data.message) {
        message(e.response.data.message, { type: "error" });
      } else {
        message("删除失败", { type: "error" });
      }
      console.log(e);
    }
  }
});

const formRules = {
  nickname: [
    {
      required: true,
      message: "请输入昵称"
    }
  ],
  username: [
    {
      required: true,
      message: "请输入账号"
    }
  ],
  password: [
    {
      required: true,
      validator: (_: any, value: any, callback: any) => {
        if (!value) {
          return callback(new Error("请输入密码"));
        }
        if (value.length < 6) {
          return callback(new Error("密码长度不能小于6位"));
        }
        callback();
      }
    }
  ],
  confirm_password: [
    {
      required: true,
      validator: (_: any, value: any, callback: any) => {
        if (!value) {
          return callback(new Error("请输入密码"));
        }
        if (formData.value.password !== value) {
          return callback(new Error("两次输入密码不一致"));
        }
        callback();
      }
    }
  ],
  roles: {
    required: true,
    message: "请选择角色"
  }
};

const submitLoading = ref<boolean>(false);

const formColumns: PlusColumn[] = [
  {
    label: "昵称",
    prop: "nickname",
    valueType: "input"
  },
  {
    label: "账号",
    prop: "username",
    valueType: "input"
  },
  {
    label: "密码",
    prop: "password",
    valueType: "input",
    fieldProps: {
      type: "password"
    }
  },
  {
    label: "确认密码",
    prop: "confirm_password",
    valueType: "input",
    fieldProps: {
      type: "password"
    }
  },
  {
    label: "头像",
    prop: "avatar",
    valueType: "img",
    renderField(value, onChange) {
      return h(
        ElUpload,
        {
          class: "avatar-uploader",
          action: UPLOAD_IMAGE_URL,
          showFileList: false,
          onSuccess: async (data: ImageItem) => {
            onChange(
              `/static/images/${data.folder}/${data.hash}.${data.format}`
            );
          }
        },
        value
          ? h("img", {
              src: SERVER_URL + value,
              class: "avatar"
            })
          : h(
              "div",
              { class: "upload-icon" },
              h(IconifyIconOnline, { icon: "ep:plus" })
            )
      );
    }
  },
  {
    label: "角色",
    prop: "roles",
    valueType: "select",
    options: [
      {
        label: "管理员",
        value: 2
      }
    ],
    fieldProps: {
      multiple: true
    }
  }
];
const formVisible = ref(false);
const formData = ref<FieldValues>({});

const handleNew = () => {
  formData.value = { roles: [2] };
  formVisible.value = true;
};

const handleConfirm = async e => {
  try {
    submitLoading.value = true;

    await registerUser(e);

    message("保存成功", { type: "success" });
    formVisible.value = false;
    refresh();
  } catch (e) {
    if (e.response.data && e.response.data.message) {
      message(e.response.data.message, { type: "error" });
    } else {
      message("保存失败", { type: "error" });
    }
    console.log(e);
  } finally {
    submitLoading.value = false;
  }
};

const handleSearch = e => {
  search();
};

// 修改密码
const changePasswordFormRules = {
  password: [
    {
      required: true,
      validator: (_: any, value: any, callback: any) => {
        if (!value) {
          return callback(new Error("请输入密码"));
        }
        if (value.length < 6) {
          return callback(new Error("密码长度不能小于6位"));
        }
        callback();
      }
    }
  ],
  confirm_password: [
    {
      required: true,
      validator: (_: any, value: any, callback: any) => {
        if (!value) {
          return callback(new Error("请输入密码"));
        }
        if (changePasswordData.value.password !== value) {
          return callback(new Error("两次输入密码不一致"));
        }
        callback();
      }
    }
  ],
  roles: {
    required: true,
    message: "请选择角色"
  }
};
const changePasswordFormColumns: PlusColumn[] = [
  {
    label: "账号",
    prop: "username",
    valueType: "input",
    fieldProps: {
      disabled: true
    }
  },
  {
    label: "密码",
    prop: "password",
    valueType: "input",
    fieldProps: {
      type: "password"
    }
  },
  {
    label: "确认密码",
    prop: "confirm_password",
    valueType: "input",
    fieldProps: {
      type: "password"
    }
  }
];
const changePasswordData = ref<FieldValues>({});
const changePasswordFormVisible = ref(false);

const handleChangePassword = async e => {
  try {
    submitLoading.value = true;
    if (changePasswordData.value.id) {
      await adminChangePassword({
        id: e.id,
        password: e.password
      });
    }
    message("保存成功", { type: "success" });
    changePasswordFormVisible.value = false;
    refresh();
  } catch (e) {
    if (e.response.data && e.response.data.message) {
      message(e.response.data.message, { type: "error" });
    } else {
      message("保存失败", { type: "error" });
    }
    console.log(e);
  } finally {
    submitLoading.value = false;
  }
};
</script>
<template>
  <div>
    <el-card shadow="never">
      <template #header>
        <div class="flex justify-between items-center">
          <span>用户管理</span>

          <el-space>
            <el-input
              v-model="searchText"
              style="width: 240px"
              clearable
              placeholder="请输入关键词"
              @change="handleSearch"
            >
              <template #append>
                <IconifyIconOnline icon="ep:search" />
              </template>
            </el-input>
            <el-button type="primary" @click="handleNew">
              <template #icon>
                <IconifyIconOnline icon="ep:plus" />
              </template>
              新增
            </el-button>
          </el-space>
        </div>
      </template>
      <pure-table
        ref="tableRef"
        border
        adaptive
        :adaptiveConfig="adaptiveConfig"
        row-key="id"
        alignWhole="center"
        showOverflowTooltip
        :loading="loading"
        :loading-config="loadingConfig"
        :data="dataList"
        :columns="columns"
        :pagination="pagination"
        @page-size-change="onSizeChange"
        @page-current-change="onCurrentChange"
      />
    </el-card>
    <PlusDialogForm
      v-model:visible="formVisible"
      v-model="formData"
      :destroy-on-close="true"
      :title="formData.id ? '编辑用户' : '新增用户'"
      width="480px"
      :form="{
        columns: formColumns,
        rules: formRules,
        labelPosition: 'top'
      }"
      @confirm="handleConfirm"
    />
    <PlusDialogForm
      v-model:visible="changePasswordFormVisible"
      v-model="changePasswordData"
      :destroy-on-close="true"
      title="修改密码"
      width="480px"
      :form="{
        columns: changePasswordFormColumns,
        rules: changePasswordFormRules,
        labelPosition: 'top'
      }"
      @confirm="handleChangePassword"
    />
  </div>
</template>
<style lang="scss">
.avatar-uploader {
  .avatar {
    width: 168px;
    height: 168px;
    display: block;
  }

  .el-upload {
    border: 1px dashed var(--el-border-color);
    border-radius: 6px;
    cursor: pointer;
    position: relative;
    overflow: hidden;
    transition: var(--el-transition-duration-fast);
  }

  .avatar-uploader .el-upload:hover {
    border-color: var(--el-color-primary);
  }

  .upload-icon {
    font-size: 28px;
    color: #8c939d;
    width: 168px;
    height: 168px;
    display: flex;
    align-items: center;
    justify-content: center;
  }
}
</style>
